package com.abhinav.designPatterns;

public class CloneTest {

	/**
	 * @param args
	 * @throws CloneNotSupportedException
	 */
	public static void main(String[] args) throws CloneNotSupportedException {
		// Original object
		Student stud = new Student("John", "Algebra");
		System.out.println("Original Object: " + stud.getName() + " - "
				+ stud.getSubj().getName());

		// Clone Object
		Student clonedStud = (Student) stud.clone();
		System.out.println("Cloned Object: " + clonedStud.getName() + " - "
				+ clonedStud.getSubj().getName());

		stud.setName("Dan");
		stud.getSubj().setName("Physics");

		System.out.println("Original Object after it is updated: "
				+ stud.getName() + " - " + stud.getSubj().getName());
		System.out
				.println("Cloned Object after updating original object: "
						+ clonedStud.getName() + " - "
						+ clonedStud.getSubj().getName());
	}

}

class Subject {
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String s) {
		name = s;
	}

	public Subject(String s) {
		name = s;
	}
}

class Student implements Cloneable {
	private String name;
	private Subject subject; // Contained object

	public Student(String name, String sub) {
		this.name = name;
		subject = new Subject(sub);
	}

	public Subject getSubj() {
		return subject;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	protected Object clone() throws CloneNotSupportedException {
		// Shallow copy
		//return super.clone();
		
		// Deep copy
		Student s = new Student(name, subject.getName());
		return s;
	}
}
